package com.bby.captcha.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.util.ObjectUtil;
import com.bby.captcha.service.ICaptchaService;
import com.bby.common.exception.BBYException;
import com.bby.common.utils.BBYUtils;
import com.bby.common.utils.StatusCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.params.SetParams;

import javax.mail.internet.MimeMessage;
import java.util.ArrayList;
import java.util.List;

/**
 * 验证码服务
 */
@Service
public class CaptchaService implements ICaptchaService {
    @Value(value = "${settings.captcha_alive_second}")
    long captcha_alive_second;
    @Value(value = "${settings.captchaWidth}")
    int captchaWidth;
    @Value(value = "${settings.captchaHigh}")
    int captchaHigh;
    private final JedisPool jedisPool;
    private final JavaMailSender javaMailSender;

    Logger logger = LoggerFactory.getLogger(this.getClass());
    public CaptchaService(JedisPool jedisPool, JavaMailSender javaMailSender) {
        this.jedisPool = jedisPool;
        this.javaMailSender = javaMailSender;
    }

    static List<Character> characterList;
    static {
        characterList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            characterList.add((char)(i+'0'));
        }
        for (int i = 0; i < 26; i++) {
            characterList.add((char)(i+'a'));
            characterList.add((char)(i+'A'));
        }
    }
    @Override
    public void createMailCaptcha(String email) throws BBYException {
        StringBuilder captcha = new StringBuilder();
        for (int i = 0; i < 8; i++) {
            captcha.append(characterList.get((int) (Math.random()*62)));
        }
        if (true){
            try (Jedis jedis = jedisPool.getResource()) {
                Thread.sleep(2000);
                logger.debug("captcha= "+captcha);
                jedis.set(email, captcha.toString(), new SetParams().ex(captcha_alive_second));
            }catch (Exception e){

            }
            return;
        }
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setFrom("joyben8080@126.com");
            helper.setTo(email);
            helper.setSubject("验证码");
            // 设置邮件内容，第二个参数设置是否支持 text/html 类型
            String text = "<h2 >bby网盘</h2>\n" +
                          "<p>欢迎使用bby网盘，您的验证码为：<string><span style=\"font-size: large;background-color: beige\"> "
                          + captcha + " </span></string>，验证码提供他人可能导致帐号被盗，请勿转发或泄漏。</p>";
            helper.setText(text, true);
            javaMailSender.send(mimeMessage);
            try (Jedis jedis = jedisPool.getResource()) {
                jedis.set(email, captcha.toString(), new SetParams().ex(captcha_alive_second));
            }
        } catch (Exception e) {
            throw new BBYException(StatusCode.MAIL_ERROR,"邮件发送失败！");
        }
    }

    @Override
    public LineCaptcha creatCaptchaById(String id){
        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(captchaWidth,captchaHigh);
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.set(id, captcha.getCode(), new SetParams().ex(captcha_alive_second));
        }
        logger.debug(id+" 获取新验证码："+captcha.getCode());
        return captcha;
    }

    /**
     * 检验验证码，不管通不通过，检验完成后验证码都会清除
     * @param id session ID
     * @param inputCode 用户输入的验证码
     */
    @Override
    public void verifyCaptcha(String id, String inputCode) throws BBYException {
        try (Jedis jedis = jedisPool.getResource()) {
            String value = jedis.get(id);
            if (ObjectUtil.isNotEmpty(value)){
                jedis.del(id);//验证码作废
                if (inputCode.equals(value)){
                    return;
                }
                throw new BBYException(StatusCode.CAPTCHA_ERROR,"验证码错误");
            }
            throw new BBYException(StatusCode.CAPTCHA_ERROR,"验证码已过期");
        }
    }

    @Override
    public String createMailToken(String id, String inputCode) throws BBYException {
        verifyCaptcha(id,inputCode);
        String token = BBYUtils.uuidStr();
        try (Jedis jedis = jedisPool.getResource()){
            jedis.set(token,id, new SetParams().ex(captcha_alive_second*10));
        }
        return token;
    }
    @Override
    public void checkMailToken(String token, String mail) throws BBYException {
        try (Jedis jedis = jedisPool.getResource()){
            if (jedis.exists(token)){
                if (!jedis.get(token).equals(mail)){
                    throw new BBYException(StatusCode.MAIL_ERROR,"邮箱错误！");
                }
            }else {
                throw new BBYException(StatusCode.MAIL_ERROR,"验证已失效！");
            }
        }
    }
}
